package com.medvalley.tcm.service.impl;

import com.google.common.collect.Lists;
import com.medvalley.tcm.base.BusinessException;
import com.medvalley.tcm.base.Constants;
import com.medvalley.tcm.controller.admin.vo.inputvo.SearchAdminUserInputVo;
import com.medvalley.tcm.controller.admin.vo.outputvo.PageDataOutputVo;
import com.medvalley.tcm.dao.AdminUserDao;
import com.medvalley.tcm.dao.OrgDao;
import com.medvalley.tcm.domain.AdminUser;
import com.medvalley.tcm.domain.Organization;
import com.medvalley.tcm.service.AdminUserService;
import com.medvalley.tcm.utils.EncryptUtils;
import com.medvalley.tcm.vo.inputvo.AdminUserInputVo;
import com.medvalley.tcm.vo.outputvo.AdminUserOutputVo;
import com.medvalley.tcm.vo.outputvo.OrgOutputVo;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @author linsong
 * @date 2019/5/8 11:09
 **/
@Service
public class AdminUserServiceImpl implements AdminUserService {

    @Autowired
    private AdminUserDao adminUserDao;

    @Autowired
    private OrgDao orgDao;

    @Override
    public AdminUserOutputVo login(String phone, String password) {
        String encryptPassword = EncryptUtils.sha256(password);
        AdminUser adminUser = adminUserDao.findOneByPhoneAndPassword(phone, encryptPassword);
        if (adminUser == null) {
            throw new BusinessException("密码错误");
        }
        AdminUserOutputVo adminUserOutputVo = new AdminUserOutputVo();
        adminUserOutputVo.setId(adminUser.getId());
        adminUserOutputVo.setName(adminUser.getName());
        adminUserOutputVo.setPhone(adminUser.getPhone());
        String orgIds = adminUser.getOrgId();
        if (!StringUtils.isEmpty(orgIds)) {
            String[] ids = orgIds.split(",");
            List<Integer> idList = Lists.newArrayList();
            for (String e : ids) {
                idList.add(Integer.valueOf(e));
            }
            List<Organization> organizationList = orgDao.findAllByIdIn(idList);
            if (!CollectionUtils.isEmpty(organizationList)) {
                List<OrgOutputVo> orgOutputVoList = Lists.newArrayList();
                organizationList.forEach(e -> {
                    OrgOutputVo orgOutputVo = new OrgOutputVo();
                    orgOutputVo.setId(e.getId());
                    orgOutputVo.setName(e.getName());
                    orgOutputVoList.add(orgOutputVo);
                });
                adminUserOutputVo.setOrgList(orgOutputVoList);
            }
        }
        return adminUserOutputVo;
    }

    @Override
    public void register(AdminUserInputVo input) {
        String phone = input.getPhone();
        AdminUser oldUser = adminUserDao.findOneByPhone(phone);
        if (oldUser != null) {
            throw new BusinessException("该手机号已经注册");
        }
        AdminUser adminUser = new AdminUser();
        adminUser.setName(input.getName());
        adminUser.setPhone(input.getPhone());
        adminUser.setOrgId(input.getOrgId());
        String encryptPassword = EncryptUtils.sha256(input.getPassword());
        adminUser.setPassword(encryptPassword);
        adminUserDao.save(adminUser);
    }

    @Override
    public PageDataOutputVo<com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo> search(SearchAdminUserInputVo searchAdminUserInputVo) {
        PageDataOutputVo<com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo> pageDataOutputVo = new PageDataOutputVo<>();
        int pageNo = searchAdminUserInputVo.getPageNo();
        int pageSize = searchAdminUserInputVo.getPageSize();
        List<com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo> adminUserOutputVos = Lists.newArrayList();
        pageDataOutputVo.setPageNo(pageNo);
        pageDataOutputVo.setPageSize(pageSize);
        pageNo = pageNo - 1 < 0 ? 0 : pageNo - 1;
        Pageable pageable = PageRequest.of(pageNo, pageSize, Sort.Direction.DESC, "id");
        Specification<AdminUser> specification = new Specification<AdminUser>() {
            @Override
            public Predicate toPredicate(Root<AdminUser> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                // 创建时间-  开始
                if (!StringUtils.isEmpty(searchAdminUserInputVo.getBeginDate())) {
                    list.add(criteriaBuilder.greaterThan(root.get("createTime").as(String.class), searchAdminUserInputVo.getBeginDate()));
                }
                // 创建时间-  结束
                if (!StringUtils.isEmpty(searchAdminUserInputVo.getEndDate())) {
                    list.add(criteriaBuilder.lessThan(root.get("createTime").as(String.class), searchAdminUserInputVo.getEndDate()));
                }
                String phone = searchAdminUserInputVo.getPhone();
                if (!StringUtils.isEmpty(phone)) {
                    list.add(criteriaBuilder.equal(root.get("phone").as(String.class), phone));
                }
                String name = searchAdminUserInputVo.getName();
                if (!StringUtils.isEmpty(name)) {
                    list.add(criteriaBuilder.like(root.get("name").as(String.class), name + "%"));
                }

                String orgId = searchAdminUserInputVo.getOrgId();
                if (!StringUtils.isEmpty(orgId)) {
                    list.add(criteriaBuilder.like(root.get("orgId").as(String.class), "%" + orgId + ",%"));
                }

                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };

        Page<AdminUser> pageData = adminUserDao.findAll(specification, pageable);
        if (pageData.hasContent()) {
            List<AdminUser> adminUserList = pageData.getContent();
            for (AdminUser au : adminUserList) {
                com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo adminUserOutputVo = new com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo();
                adminUserOutputVo.setId(au.getId());
                adminUserOutputVo.setName(au.getName());
                adminUserOutputVo.setPhone(au.getPhone());
                adminUserOutputVo.setOrgId(au.getOrgId());
                adminUserOutputVo.setCreateTime(DateFormatUtils.format(au.getCreateTime(), Constants.YYYY_MM_DD_HH_MM_SS));
                adminUserOutputVos.add(adminUserOutputVo);
            }
        }

        pageDataOutputVo.setTotalPageCount(pageData.getTotalPages());
        pageDataOutputVo.setTotalElement(pageData.getTotalElements());
        pageDataOutputVo.setPageData(adminUserOutputVos);

        return pageDataOutputVo;
    }

    @Override
    public com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo detail(int id) {
        AdminUser adminUser = adminUserDao.findById(id).orElseThrow(() -> new BusinessException("查无此人"));
        com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo adminUserOutputVo = new com.medvalley.tcm.controller.admin.vo.outputvo.AdminUserOutputVo();
        adminUserOutputVo.setId(adminUser.getId());
        adminUserOutputVo.setName(adminUser.getName());
        adminUserOutputVo.setPhone(adminUser.getPhone());
        adminUserOutputVo.setOrgId(adminUser.getOrgId());
        adminUserOutputVo.setCreateTime(DateFormatUtils.format(adminUser.getCreateTime(), Constants.YYYY_MM_DD_HH_MM_SS));
        adminUserOutputVo.setPassword("*******");
        return adminUserOutputVo;
    }

    @Override
    public void delete(int id) {
        adminUserDao.deleteById(id);
    }

    @Override
    public void update(AdminUserInputVo adminUserInputVo) {
        AdminUser adminUser = adminUserDao.findById(adminUserInputVo.getId()).orElseThrow(() -> new BusinessException("查无此人"));
        adminUser.setPhone(adminUserInputVo.getPhone());
        adminUser.setName(adminUserInputVo.getName());
        adminUser.setOrgId(adminUserInputVo.getOrgId());
        if (!StringUtils.isEmpty(adminUserInputVo.getPassword())) {
            adminUser.setPassword(EncryptUtils.sha256(adminUserInputVo.getPassword()));
        }
        adminUserDao.save(adminUser);
    }


}
